package com.astrofizzbizz.stoneedgegui.app;


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Desktop;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.text.DecimalFormat;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.SwingConstants;

import com.astrofizzbizz.simpleXml.SimpleXmlException;
import com.astrofizzbizz.simpleXml.SimpleXmlReader;
import com.astrofizzbizz.simpleXml.SimpleXmlWriter;
import com.astrofizzbizz.stoneedgegui.utilities.StarCoordUtilities;
import com.astrofizzbizz.stoneedgegui.utilities.StoneEdgeIIIException;



public class AstroTarget
{
	private String ra = null;
	private String dec = null;
	private String epoch = null;
	private String name = null;
	private String alias = null;
	private String link = null;
	private String imagelink = null;
	private String rank = null;
	private String magn = null;
	private String type = null;
	private String horizons = null;
	private JPanel menuPanel = null;
	private JRadioButton targetButton;
	private double altDeg = 90.0;
	private double azDeg = 90.0;
	private double airMass;
	private Color airMassColor = Color.GREEN;
	private boolean visible = false;
	private DecimalFormat df = new DecimalFormat("###.#");
	private JLabel raLabel = new JLabel();
	private JLabel decLabel = new JLabel();
	private JLabel altLabel = new JLabel();
	private JLabel azLabel = new JLabel();
	private JLabel airMassLabel = new JLabel();
	private StoneEdgeIIIGui stoneEdgeIIIGui;
	private int catIndex;
	
	public AstroTarget(SimpleXmlReader targetTag, StoneEdgeIIIGui stoneEdgeIIIGui, int catIndex) throws StoneEdgeIIIException 
	{
		this.stoneEdgeIIIGui = stoneEdgeIIIGui;
		this.catIndex = catIndex;
		try {ra = targetTag.attribute("ra");} catch (SimpleXmlException e) {}
		try {dec = targetTag.attribute("dec");} catch (SimpleXmlException e) {}
		try {epoch = targetTag.attribute("epoch");} catch (SimpleXmlException e) {epoch = "2000.0";}
		try {name = targetTag.attribute("name");} catch (SimpleXmlException e) {}
		try {alias = targetTag.attribute("alias");} catch (SimpleXmlException e) {}
		try {link = targetTag.attribute("link");} catch (SimpleXmlException e) {}
		try {imagelink = targetTag.attribute("imagelink");} catch (SimpleXmlException e) {}
		try {rank = targetTag.attribute("rank");} catch (SimpleXmlException e) {}
		try {magn = targetTag.attribute("magn");} catch (SimpleXmlException e) {}
		try {type = targetTag.attribute("type");} catch (SimpleXmlException e) {type = "unknown";}
		try {horizons = targetTag.attribute("horizons");} catch (SimpleXmlException e) {}

		menuPanel = new JPanel();
		menuPanel.setLayout(new GridLayout(1,8));
		targetButton = new JRadioButton();
		targetButton.addActionListener(new AstroTargetActionListener("target"));
		
		JLabel targetLabel = new JLabel(" "+ name + " ");
		
		targetButton.setHorizontalAlignment(SwingConstants.CENTER);
		raLabel.setHorizontalAlignment(SwingConstants.CENTER);
		targetLabel.setHorizontalAlignment(SwingConstants.CENTER);
		raLabel.setHorizontalAlignment(SwingConstants.CENTER);
		decLabel.setHorizontalAlignment(SwingConstants.CENTER);
		azLabel.setHorizontalAlignment(SwingConstants.CENTER);
		altLabel.setHorizontalAlignment(SwingConstants.CENTER);
		airMassLabel.setHorizontalAlignment(SwingConstants.CENTER);
		
		menuPanel.add(targetButton);
		menuPanel.add(targetLabel);
		menuPanel.add(raLabel);
		menuPanel.add(decLabel);
		menuPanel.add(altLabel);
		menuPanel.add(azLabel);
		menuPanel.add(airMassLabel);
		
		JButton infoButton = new JButton("?");
//		infoButton.setPreferredSize(new Dimension(50,50));
		infoButton.addActionListener(new AstroTargetActionListener("info"));
		JPanel infoButtonPanel = new JPanel();
		infoButtonPanel.setLayout(new BorderLayout(0,0));
		infoButtonPanel.add(infoButton, BorderLayout.CENTER);
//		infoButton.setHorizontalAlignment(SwingConstants.CENTER);
//		infoButton.setVerticalAlignment(SwingConstants.CENTER);
		menuPanel.add(infoButtonPanel);
		
		update();
	}
	public AstroTarget(String name, String ra, String dec, StoneEdgeIIIGui stoneEdgeIIIGui) throws StoneEdgeIIIException 
	{
		this.stoneEdgeIIIGui = stoneEdgeIIIGui;
		this.catIndex = -1;
		this.ra = new String(ra);
		this.dec = new String(dec);
		this.name = new String(name);
		this.epoch = "2000";
		this.type = "unknown";
		
		update();
	}
	public void update() throws StoneEdgeIIIException
	{
		if (getType().toLowerCase().equals("planet"))
		{
			String[] raDec = {"",""};
			try {raDec = StarCoordUtilities.horizonsRaDec(
						getHorizons(), 
						stoneEdgeIIIGui.getUpdateDate(), 
						stoneEdgeIIIGui.getTelescopeInfo().getLongitudeDeg(), 
						stoneEdgeIIIGui.getTelescopeInfo().getLatitudeDeg(), false);
			} catch (StoneEdgeIIIException e) {}
			ra = raDec[0]; 
			dec = raDec[1]; 
			epoch = "2000.0";
		}
		if (ra != null) if ( ra.indexOf("+") > -1) ra = ra.substring(ra.indexOf("+") + 1);
		if (dec != null) if ( dec.indexOf("+") > -1) dec = dec.substring(dec.indexOf("+") + 1);
        double[] altAzDeg =  StarCoordUtilities.getAltAzDeg(StarCoordUtilities.raDeg(ra), StarCoordUtilities.decDeg(dec), 
        		stoneEdgeIIIGui.getTelescopeInfo().getLongitudeDeg(), 
        		stoneEdgeIIIGui.getTelescopeInfo().getLatitudeDeg(), 
        		stoneEdgeIIIGui.getUpdateDate());
        altDeg = altAzDeg[0];
        azDeg = altAzDeg[1];
		airMass = 90.0 - altDeg;
		airMass = 1.0 / Math.cos(airMass * Math.PI / 180.0);
		airMassColor = Color.GREEN.darker();
		if ((1.4 <= airMass) && (airMass <= 2.0) ) airMassColor = Color.ORANGE;
		if (2.0 < airMass )  airMassColor = Color.RED;
		visible = isVisible(altAzDeg);
		
		if (catIndex >= 0)
		{
			raLabel.setText(" "+ ra + " ");
			decLabel.setText(" "+ dec + " ");
			altLabel.setText(" "+  df.format(altDeg) + " ");
			azLabel.setText(" "+  df.format(azDeg) + " ");
			airMassLabel.setText( " "+ df.format(airMass) + " ");
			airMassLabel.setForeground(airMassColor);
			if (!visible) menuPanel.setVisible(false);
			if (visible) menuPanel.setVisible(true);
		}
	}
	public void outputDesc(SimpleXmlWriter xw)
	{
		xw.openXmlTag("target");
		if (ra != null) xw.setAttribute("ra", ra);
		if (dec != null) xw.setAttribute("dec", dec);
		if (epoch != null) xw.setAttribute("epoch", epoch);
		if (name != null) xw.setAttribute("name", name);
		if (alias != null) xw.setAttribute("alias", alias);
		if (link != null) xw.setAttribute("link", link);
		if (imagelink != null) xw.setAttribute("imagelink", imagelink);
		if (rank != null) xw.setAttribute("rank", rank);
		if (magn != null) xw.setAttribute("magn", magn);
		if (type != null) xw.setAttribute("type", type);
		if (horizons != null) xw.setAttribute("horizons", horizons);
		xw.closeXmlTag("target");
	}
	public boolean isVisible(double[] altAz)  
	{
		if (isAtAltLimit(altAz)) return false;
		if (isAtRaLimit()) return false;
		if (isAtDecLimit()) return false;
		return true;
	}
	public boolean isAtAltLimit(double[] altAz)
	{
		if (altAz[0]  < stoneEdgeIIIGui.getTelescopeInfo().getAltLimit()) return true;
		return false;
	}
	public boolean isAtRaLimit()
	{
		double hourAngleDeg 
			= StarCoordUtilities.lmstDeg(stoneEdgeIIIGui.getUpdateDate(), 
					stoneEdgeIIIGui.getTelescopeInfo().getLongitudeDeg())
			- StarCoordUtilities.raDeg(ra);
		if (hourAngleDeg >  180.0 ) hourAngleDeg = hourAngleDeg - 360;
		if (hourAngleDeg < -180.0 ) hourAngleDeg = hourAngleDeg + 360;
		if (hourAngleDeg < stoneEdgeIIIGui.getTelescopeInfo().getLowerEastRaLimit()) return true;
		if (hourAngleDeg > stoneEdgeIIIGui.getTelescopeInfo().getUpperWestRaLimit()) return true;
		return false;
	}
	public boolean isAtDecLimit()
	{
		double decDeg = StarCoordUtilities.decDeg(dec);
		if (decDeg > stoneEdgeIIIGui.getTelescopeInfo().getUpperDecLimit()) return true;
		if (decDeg < stoneEdgeIIIGui.getTelescopeInfo().getLowerDecLimit()) return true;
		return false;
	}
	private class AstroTargetActionListener implements ActionListener
	{
		String actionString;
		private AstroTargetActionListener(String actionString)
		{
			this.actionString = actionString;
		}

		@Override
		public void actionPerformed(ActionEvent actionEvent) 
		{
			if (actionString.equals("info")) 
			{
				try {
					URL imageLinkUrl = new URL(link);
			    	Desktop.getDesktop().browse(imageLinkUrl.toURI());
				} 
				catch (MalformedURLException e) {} 
				catch (IOException e) {} 
				catch (URISyntaxException e) {}
			}
			if (actionString.equals("target")) 
			{
				try {stoneEdgeIIIGui.getAstroCatalog().setSelectedTarget(catIndex);} 
				catch (StoneEdgeIIIException e) {e.messageDialog(stoneEdgeIIIGui);}
			}
		}
		
	}
	public String getRa() {return ra;}
	public String getDec() {return dec;}
	public double getAltDeg() {return altDeg;}
	public double getAzDeg() {return azDeg;}
	public String getEpoch() {return epoch;}
	public String getName() {return name;}
	public String getAlias() {return alias;}
	public String getLink() {return link;}
	public String getImagelink() {return imagelink;}
	public String getRank() {return rank;}
	public String getMagn() {return magn;}
	public String getType() {return type;}
	public String getHorizons() {return horizons;}
	public boolean isVisible() {return visible;}
	public JPanel getMenuPanel() {return menuPanel;}
	public JRadioButton getTargetButton() {return targetButton;}
	public void setRa(String ra) {this.ra = ra;}
	public void setDec(String dec) {this.dec = dec;}
}
